package sg.com.techstudio.cfoconnect.dao;

import java.util.Calendar;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import sg.com.techstudio.cfoconnect.filter.RegisterFilter;
import sg.com.techstudio.cfoconnect.obj.RegisterObj;

@Repository("registerDao")
@Transactional
public class RegisterDao {
	private static final Log log = LogFactory.getLog(RegisterDao.class);
	
	@Autowired
	private SessionFactory sessionFactory;
	
	@Autowired
	private EmailDao emailDao;
	
	@SuppressWarnings("unchecked")
	@Transactional(readOnly=true)
	public List<RegisterObj> getAllRegisterObj(){
		log.debug("update() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(RegisterObj.class);
		c.addOrder(Order.asc("id"));
		c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return c.list();
	}
	
	@Transactional(readOnly=true)
	public RegisterObj get(Long id) {
		return (RegisterObj) sessionFactory.getCurrentSession().get(RegisterObj.class, id);
	}
	
	public void update(RegisterObj r) {
		log.debug("update() entry");
		r.setUpdatedDate(Calendar.getInstance().getTime());
		sessionFactory.getCurrentSession().update(r);
	}
	
	public void saveRegistration(RegisterObj r) {
		log.debug("saveRegistration() entry");
		r.setCreatedDate(Calendar.getInstance().getTime());
		sessionFactory.getCurrentSession().save(r);
		log.debug("saveRegistration() exit");
	}
	
	public void saveOrUpdate(RegisterObj r) {
		log.debug("saveOrUpdate() entry");
		r.setCreatedDate(Calendar.getInstance().getTime());
		sessionFactory.getCurrentSession().saveOrUpdate(r);
		log.debug("saveOrUpdate() exit");
	}
	
	public void confirmAllStatus(RegisterObj r) {
		log.debug("confirmAllStatus() entry");
		setAllStatus(r, 1);
	}
	
	public void setAllStatus(RegisterObj r, int status) {
		log.debug("setAllStatus() entry");
		r.setStatus(status);
	}
	
	public void setAllStatusAndUpdate(List<RegisterObj> regList, RegisterFilter filter, int status) {
		for(RegisterObj r: regList)
			if(r.getId().equals(filter.getId())) {
				setAllStatus(r, status);
				update(r);
				return;
			}
	}
	
	/*
	public void initParticipantList(RegisterObj r) {
		log.debug("initParticipantList() entry");
		if(r.getParticipantList()==null)
			r.setParticipantList(new LinkedList<ParticipantObj>());
		if(r.getParticipantList().size()>r.getNoParticipant())
			while(r.getParticipantList().size()>r.getNoParticipant()
					&& r.getParticipantList().size()>0)
				r.getParticipantList().remove(r.getParticipantList().size()-1);
		else if(r.getParticipantList().size()<r.getNoParticipant())
			while(r.getParticipantList().size()<r.getNoParticipant())
				r.getParticipantList().add(new ParticipantObj(r));
	}
	
	public void translateProgrammePackage(RegisterObj r) {
		if(r==null||r.getParticipantSize()==0)
			return;
		for(ParticipantObj p: r.getParticipantList())
			translateProgrammePackage(p);
	}
	
	public int countParticipantInList(List<RegisterObj> registerList) {
		log.debug("countParticipantInList() entry");
		if(registerList==null)
			return 0;
		int count = 0;
		for(RegisterObj r: registerList) {
			if(r.getParticipantList()==null)
				continue;
			count+=r.getParticipantSize();
		}
		return count;
	}
	
	protected void translateProgrammePackage(ParticipantObj p) {
		if(p.getPackageId()==null) {
			p.setMain(false);
			p.setBreakout1(null);
			p.setBreakout2(null);
			return;
		}
		p.setMain(p.getPackageId()==1 || p.getPackageId()==2);
		if(p.getPackageId()==2) {
			p.setBreakout1(null);
			p.setBreakout2(null);
		} else {
			p.setBreakout1(p.getPackageId()==1?p.getBreakoutChoice()[0]:p.getBreakoutChoice()[2]);
			p.setBreakout2(p.getPackageId()==1?p.getBreakoutChoice()[1]:p.getBreakoutChoice()[3]);
		}
	}
	
	public void copyCompanyInfo(RegisterObj r, List<CompanyObj> companyList) {
		log.debug("copyCompanyInfo() entry");
		if(companyList==null)
			return;
		for(CompanyObj c: companyList) {
			if(r.getCompanyId().equals(c.getId())) {
				r.setCompanyName(c.getName());
				r.setCompanyAddress(c.getAddress());
				return;
			}
		}
		log.debug("copyCompanyInfo() exit. company not found.");
	}
	
	public void clearCompanyInfo(RegisterObj r) {
		if(r==null)
			return;
		r.setCompanyId(null);
		r.setCompanyName(null);
		r.setCompanyAddress(null);
	}

	
	public void clearParticipantProgramme(ParticipantObj p) {
		if(p==null)
			return;
		p.setMain(false);
		p.setBreakout1(null);
		p.setBreakout2(null);
		p.setPost1(false);
		p.setPost2(false);
	}
	
	public void deleteLastParticipant(RegisterObj r) {
		log.debug("deleteLastParticipant() entry");
		if(r==null||r.getParticipantList()==null
				|| r.getParticipantList().isEmpty())
			return;
		r.getParticipantList().remove(r.getParticipantList().size()-1);
	}
	public void deleteAllParticipant(RegisterObj r) {
		log.debug("deleteAllParticipant() entry");
		if(r==null||r.getParticipantList()==null
				|| r.getParticipantList().isEmpty())
			return;
		r.getParticipantList().clear();
	}
	
	public void addParticipant(RegisterObj r, ParticipantObj p) {
		log.debug("addParticipant() entry");
		if(r==null||p==null)
			return;
		p.setCompany(r.getCompanyName());//copy company name for registrant counting
		r.getParticipantList().add(p);
	}
	
	public Long getNoRegisteredByCompany(RegisterObj r) {
		log.debug("getNoRegisteredByCompany() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("company", r.getCompanyName()));
		c.setProjection(Projections.rowCount());
		return (Long) c.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	protected List<ParticipantObj> getParticipantListByCompany(RegisterObj r){
		log.debug("getParticipantListByCompany() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("company", r.getCompanyName()));
		return c.list();
	}
	
	
	
	protected double round(double d) {
		return (double) Math.round(d);
	}
	
	public void confirmAllStatus(RegisterObj r) {
		log.debug("confirmAllStatus() entry");
		setAllStatus(r, 1);
	}
	
	public void setAllStatus(RegisterObj r, int status) {
		log.debug("setAllStatus() entry");
		r.setStatus(status);
		if(r.getParticipantList()!=null)
			for(ParticipantObj p: r.getParticipantList())
				p.setStatus(status);
	}
	
	public void setAllStatusAndUpdate(List<RegisterObj> regList, RegisterFilter filter, int status) {
		for(RegisterObj r: regList)
			if(r.getId().equals(filter.getId())) {
				setAllStatus(r, status);
				update(r);
				return;
			}
	}
	
	public void postRegistrationHandling(RegisterObj r) {
		log.debug("postRegistrationHandling() entry");
		if(r==null)
			return;
		if(r.getAmount()==0)
			emailDao.sendParticipantEmail(r);
		else
			emailDao.sendChequeEmail(r);
	}
	*/
}
